package com.graduation.project.service.grade.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.graduation.project.entity.dto.grade.GetThesisGradeDTO;
import com.graduation.project.entity.dto.grade.SaveOrUpdateGradeDTO;
import com.graduation.project.entity.other.LoginUser;
import com.graduation.project.entity.po.Grade;
import com.graduation.project.entity.po.Task;
import com.graduation.project.entity.po.Thesis;
import com.graduation.project.entity.vo.UserTaskGradeVO;
import com.graduation.project.entity.vo.grade.ThesisGradeVO;
import com.graduation.project.enums.ResultCodeEnum;
import com.graduation.project.mapper.grade.GradeMapper;
import com.graduation.project.mapper.process.ListThesisMapper;
import com.graduation.project.mapper.process.ThesisMapper;
import com.graduation.project.service.grade.GradeService;
import com.graduation.project.service.process.ThesisService;
import com.graduation.project.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class GradeServiceImpl extends ServiceImpl<GradeMapper, Grade> implements GradeService {

    @Autowired
    private ListThesisMapper listThesisMapper;
    @Autowired
    private GradeMapper gradeMapper;

    @Override
    public ResultUtil<?> getThesisGrade(GetThesisGradeDTO input) {
        Grade grade = gradeMapper.selectOne(new LambdaQueryWrapper<Grade>()
                .eq(Grade::getGradeType, input.getGradeType())
                .eq(Grade::getTaskId, input.getTaskId()));

        ThesisGradeVO output = new ThesisGradeVO();
        if (ObjectUtil.isNotEmpty(grade)) {
            BeanUtil.copyProperties(grade, output);
        }
        return ResultUtil.Success(ResultCodeEnum.SUCCESS, output);
    }

    @Override
    public ResultUtil<?> gradeThesis(SaveOrUpdateGradeDTO input) {
        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authenticationToken.getPrincipal();
        String userCode = loginUser.getUser().getUserCode();

        // 判断所评是否存在
        LambdaQueryWrapper<Grade> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Grade::getTaskId, input.getTaskId())
                .eq(Grade::getGradeType, input.getGradeType());
        Grade res = gradeMapper.selectOne(lambdaQueryWrapper);

        // 指导教师评阅成绩
        if (input.getGradeType().equals(0)) {
            if (ObjectUtil.isEmpty(input.getTopicScore()) || ObjectUtil.isEmpty(input.getProcessScore()) || ObjectUtil.isEmpty(input.getAbilityScore()) || ObjectUtil.isEmpty(input.getQualityScore())) {
                return ResultUtil.Failed(ResultCodeEnum.FILED.getCode(), "成绩不能为空");
            }
            if (ObjectUtil.isNotEmpty(res)) {
                // 重评
                res.setTopicScore(input.getTopicScore());
                res.setProcessScore(input.getProcessScore());
                res.setAbilityScore(input.getAbilityScore());
                res.setQualityScore(input.getQualityScore());
                res.setGradeScore(input.getTopicScore() + input.getProcessScore() + input.getAbilityScore() + input.getQualityScore());
                res.setGradeRemark(input.getGradeRemark());
                res.setUserCode(userCode);
                try {
                    gradeMapper.updateById(res);
                } catch (Exception e) {
                    throw new RuntimeException("评分失败");
                }
            } else {
                Grade grade = new Grade();
                BeanUtil.copyProperties(input, grade);
                grade.setGradeScore(input.getTopicScore() + input.getProcessScore() + input.getAbilityScore() + input.getQualityScore());
                grade.setUserCode(userCode);
                try {
                    gradeMapper.insert(grade);
                } catch (Exception e) {
                    throw new RuntimeException("评分失败");
                }
            }
        }
        // 评阅教师评阅成绩
        if (input.getGradeType().equals(1)) {
            if (ObjectUtil.isEmpty(input.getTopicScore()) || ObjectUtil.isEmpty(input.getAbilityScore()) || ObjectUtil.isEmpty(input.getQualityScore())) {
                return ResultUtil.Failed(ResultCodeEnum.FILED.getCode(), "成绩不能为空");
            }
            if (ObjectUtil.isNotEmpty(res)) {
                // 重评
                res.setTopicScore(input.getTopicScore());
                res.setAbilityScore(input.getAbilityScore());
                res.setQualityScore(input.getQualityScore());
                res.setGradeScore(input.getTopicScore() + input.getAbilityScore() + input.getQualityScore());
                res.setGradeRemark(input.getGradeRemark());
                res.setUserCode(userCode);
                try {
                    gradeMapper.updateById(res);
                } catch (Exception e) {
                    throw new RuntimeException("评分失败");
                }
            } else {
                Grade grade = new Grade();
                BeanUtil.copyProperties(input, grade, "processScore");
                grade.setGradeScore(input.getTopicScore() + input.getAbilityScore() + input.getQualityScore());
                grade.setUserCode(userCode);
                try {
                    gradeMapper.insert(grade);
                } catch (Exception e) {
                    throw new RuntimeException("评分失败");
                }
            }
        }
        // 答辩组长录入成绩
        if (input.getGradeType().equals(2)) {
            if (ObjectUtil.isEmpty(input.getGradeScore())) {
                return ResultUtil.Failed(ResultCodeEnum.FILED.getCode(), "成绩不能为空");
            }
            if (ObjectUtil.isNotEmpty(res)) {
                // 重评
                res.setGradeScore(input.getGradeScore());
                res.setGradeRemark(input.getGradeRemark());
                res.setUserCode(userCode);
                try {
                    gradeMapper.updateById(res);
                } catch (Exception e) {
                    throw new RuntimeException("评分失败");
                }
            } else {
                Grade grade = new Grade();
                grade.setTaskId(input.getTaskId());
                grade.setGradeType(input.getGradeType());
                grade.setGradeScore(input.getGradeScore());
                grade.setGradeRemark(input.getGradeRemark());
                grade.setUserCode(userCode);
                try {
                    gradeMapper.insert(grade);
                } catch (Exception e) {
                    throw new RuntimeException("评分失败");
                }
            }
        }

        return ResultUtil.Success(ResultCodeEnum.SUCCESS.getCode(), "评分成功");
    }

    @Override
    public ResultUtil<?> getUserTaskScore() {
        // 获取用户信息
        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authenticationToken.getPrincipal();
        String userCode = loginUser.getUser().getUserCode();
        // 查询用户申报过审的课题有哪些
        List<Map<String, Object>> taskList = listThesisMapper.listUserScoreTaskIds(userCode);
        List<Map<String, Object>> userTaskScoreList = new ArrayList<>();
        for (Map<String, Object> task : taskList) {
            // 查询出每个课题的所有成绩
            LambdaQueryWrapper<Grade> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Grade::getTaskId, task.get("id"));
            List<Grade> gradeList = gradeMapper.selectList(lambdaQueryWrapper);
            Map<String, Object> map = new HashMap<>();
            map.put("taskName", task.get("task_name"));
            for (Grade grade : gradeList) {
                UserTaskGradeVO userTaskGradeVO = new UserTaskGradeVO();
                BeanUtil.copyProperties(grade, userTaskGradeVO);
                switch (grade.getGradeType()) {
                    case 0: map.put("adviserGrade", userTaskGradeVO);break;
                    case 1: map.put("evaluatorGrade", userTaskGradeVO);break;
                    case 2: map.put("defenseGroupGrade", userTaskGradeVO);break;
                    default: break;
                }
            }
            userTaskScoreList.add(map);
        }
        return ResultUtil.Success(ResultCodeEnum.SUCCESS.getCode(), "查询成功", userTaskScoreList);
    }
}
